package com.knowif.util.commonUtil;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.util.*;

import org.apache.commons.lang.StringUtils;


public class StringUtil {
	public final static Random random = new Random();
	final static char[] hexChar = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

	public static String nullToString(int value) {
		return value == 0 ? "" : String.valueOf(value);
	}

	public static String nullToString(String value) {
		return (value == null ? "" : value);
	}

	public static String nullToString(String value, String encode) {
		if (value == null)
			return "";
		if (encode == null || encode.length() == 0)
			return value;
		try {
			return new String(value.getBytes("ISO-8859-1"), encode);
		} catch (UnsupportedEncodingException e) {
			return value;
		}
	}

	public static String emptyToString(String value, String defaultString) {
		if (value == null || value.trim().length() == 0)
			return defaultString;

		return value;
	}

	public static String left(String value, int len) {
		String rc = nullToString(value);
		if (len < 0)
			len = 0;

		return rc.length() > len ? rc.substring(0, len) : rc;
	}

	public static String right(String value, int len) {
		String rc = nullToString(value);
		if (len < 0)
			len = 0;

		return rc.length() > len ? rc.substring(rc.length() - len) : rc;
	}

	public static String paddingStringLeft(String s, int width, char ch) {
		if (s == null)
			s = "";
		for (int i = s.length(); i < width; i++)
			s = ch + s;

		return s;
	}

	public static String paddingStringRight(String s, int width, char ch) {
		if (s == null)
			s = "";
		for (int i = s.length(); i < width; i++)
			s = s + ch;

		return s;
	}

	public static short stringToShort(String strNumber) {
		return stringToShort(strNumber, (short) 0);
	}

	public static short stringToShort(String strNumber, short defaultValue) {
		short result = defaultValue;
		try {
			if (strNumber != null && strNumber.length() > 0)
				result = Short.parseShort(strNumber);
		} catch (NumberFormatException e) {
		}
		return result;
	}

	public static int stringToInt(String strNumber) {
		return stringToInt(strNumber, 0);
	}

	public static int stringToInt(String strNumber, int defaultValue) {
		int result = defaultValue;
		try {
			if (strNumber != null && strNumber.length() > 0)
				result = Integer.parseInt(strNumber);
		} catch (NumberFormatException e) {
		}
		return result;
	}

	public static long stringToLong(String strNumber) {
		return stringToLong(strNumber, 0);
	}

	public static long stringToLong(String strNumber, long defaultValue) {
		long result = defaultValue;
		try {
			if (strNumber != null && strNumber.length() > 0)
				result = Long.parseLong(strNumber);
		} catch (NumberFormatException e) {
		}
		return result;
	}

	public static double stringToDouble(String strNumber) {
		return stringToDouble(strNumber, 0.00);
	}

	public static double stringToDouble(String strNumber, double defaultValue) {
		double result = defaultValue;
		try {
			if (strNumber != null && strNumber.length() > 0)
				result = Double.parseDouble(strNumber);
		} catch (NumberFormatException e) {
		}
		return result;
	}

	public static java.util.Date stringToDate(String strDate) {
		return stringToDate(strDate, new java.util.Date(0));
	}

	public static java.util.Date stringToDate(String strDate, java.util.Date defaultValue) {
		java.util.Date date = defaultValue;
		try {
			if (strDate != null && strDate.length() > 0)
				date = java.sql.Date.valueOf(strDate);
		} catch (IllegalArgumentException e) {
		}
		return date;
	}

	public static java.sql.Date stringToSqlDate(String strDate) {
		return stringToSqlDate(strDate, null);
	}

	public static java.sql.Date stringToSqlDate(String strDate, java.sql.Date defaultValue) {
		java.sql.Date date = defaultValue;
		try {
			if (strDate != null && strDate.length() > 0)
				date = java.sql.Date.valueOf(strDate);
		} catch (IllegalArgumentException e) {
		}
		return date;
	}

	public static Time stringToSqlTime(String strTime) {
		return stringToSqlTime(strTime, null);
	}

	public static Time stringToSqlTime(String strTime, Time defaultValue) {
		Time time = defaultValue;
		try {
			if (strTime != null && strTime.length() > 0) {
				if (strTime.indexOf(':') == strTime.lastIndexOf(':'))
					strTime += ":00";
				time = Time.valueOf(strTime);
			}
		} catch (IllegalArgumentException e) {
		}
		return time;
	}

	public static Timestamp stringToTimestamp(String strTime) {
		return stringToTimestamp(strTime, new Timestamp(0));
	}

	public static Timestamp stringToTimestamp(String strTime, Timestamp defaultValue) {
		Timestamp time = defaultValue;
		try {
			if (strTime != null && strTime.length() > 0)
				time = java.sql.Timestamp.valueOf(strTime);
		} catch (IllegalArgumentException e) {
		}
		return time;
	}

	public static boolean isNumber(String s) {
		if (s == null || s.length() == 0)
			return false;
		byte b[] = s.getBytes();
		for (int i = 0; i < b.length; i++) {
			if (b[i] < '0' || b[i] > '9')
				return false;
		}

		return true;
	}

	public static String shortString(String value, int len) {
		String rc = nullToString(value);
		if (rc.length() <= len && len > 0)
			return rc;

		return value.substring(0, len) + "...";
	}

	public static String shortAnsiString(String value, int len) {
		String rc = nullToString(value);
		if (rc.getBytes().length > len) {
			int trimLen = (rc.getBytes().length - len + 1) / 2;
			int strLen = rc.length();
			while (rc.substring(0, strLen - trimLen).getBytes().length > len) {
				trimLen++;
			}
			rc = value.substring(0, strLen - trimLen) + "...";
		}

		return rc;
	}

	public static String formatCurrency(double value) {
		DecimalFormat df = new DecimalFormat("0.00");
		return df.format(value);
	}

	public static String setSentencePeriod(String value) {
		if (value == null || value.trim().length() == 0) {
			return "";
		}

		if (!value.matches(".*[,.，。]$")) {
			value += "。";
		}

		return value;
	}

	public static boolean isEmpty(String value) {
		if (value == null || value.trim().length() == 0 || "null".equalsIgnoreCase(value)) {
			return true;
		}
		return false;
	}

	public static String getRandomString(int length) {
		StringBuffer sb = new StringBuffer(length);
		for (int i = 0; i < length; i++) {
			sb.append(hexChar[random.nextInt(16)]);
		}
		return sb.toString();
	}

	public static String getRandomNumber(int length) {
		StringBuffer sb = new StringBuffer(length);
		for (int i = 0; i < length; i++) {
			sb.append(random.nextInt(10));
		}
		return sb.toString();
	}

	public static String getSafeString(String value) {
		return value == null ? null : value.replaceAll("'", "\\\\'");
	}

	public static byte[] hex2Byte(String str) {
		byte[] rc = null;
		if (str == null || str.length() == 0)
			return rc;
		int len = str.length() / 2;
		rc = new byte[len];
		for (int i = 0; i < len; i++) {
			try {
				rc[i] = (byte) (Integer.parseInt(str.substring(2 * i, 2 * i + 2), 16) & 0XFF);
			} catch (NumberFormatException e) {
			}
		}

		return rc;
	}

	public static String byte2Hex(byte b[]) {
		if (b == null)
			return "";
		StringBuffer tmp = new StringBuffer();
		int len = b.length;
		for (int i = 0; i < len; i++) {
			tmp.append(hexChar[(b[i] >>> 4) & 0x0F]);
			tmp.append(hexChar[b[i] & 0x0F]);
		}

		return tmp.toString();
	}

	public static float stringSimilarity(String str1, String str2) {
		// 计算两个字符串的长度。
		int len1 = str1.length();
		int len2 = str2.length();
		// 建立上面说的数组，比字符长度大一个空间
		int[][] dif = new int[len1 + 1][len2 + 1];
		// 赋初值，步骤B。
		for (int a = 0; a <= len1; a++) {
			dif[a][0] = a;
		}
		for (int a = 0; a <= len2; a++) {
			dif[0][a] = a;
		}
		// 计算两个字符是否一样，计算左上的值
		int temp;
		for (int i = 1; i <= len1; i++) {
			for (int j = 1; j <= len2; j++) {
				if (str1.charAt(i - 1) == str2.charAt(j - 1)) {
					temp = 0;
				} else {
					temp = 1;
				}
				// 取三个值中最小的
				dif[i][j] = min(dif[i - 1][j - 1] + temp, dif[i][j - 1] + 1, dif[i - 1][j] + 1);
			}
		}

		return 1 - (float) dif[len1][len2] / Math.max(len1, len2);
	}

	// 得到最小值
	private static int min(int... is) {
		int min = Integer.MAX_VALUE;
		for (int i : is) {
			if (min > i) {
				min = i;
			}
		}
		return min;
	}

//	public static String traditionalToSimplified(String s) {
//		if (s == null || s.length() == 0) {
//			return s;
//		}
//		char[] buff = s.toCharArray();
//		for (int i = 0; i < buff.length; i++) {
//			int pos = Arrays.binarySearch(traditional, buff[i]);
//			if (pos >= 0) {
//				buff[i] = simplified[pos];
//			}
//		}
//
//		return new String(buff);
//	}

	public static String camel2Dash(String value) {
		if (value == null || value.length() == 0) {
			return value;
		}
		StringBuffer sb = new StringBuffer();
		for (char c : value.toCharArray()) {
			if (c >= 'A' && c <= 'Z') {
				sb.append('_');
				sb.append((char) (c + 0x20));
			} else {
				sb.append(c);
			}
		}

		return sb.toString();
	}

	public static String dash2Camel(String value) {
		if (value == null || value.length() == 0) {
			return value;
		}
		StringBuffer sb = new StringBuffer();
		char[] chars = value.toCharArray();
		for (int i = 0; i < chars.length; i++) {
			if (chars[i] == '_' && i < chars.length && chars[i + 1] >= 'a' && chars[i + 1] <= 'z') {
				sb.append((char) (chars[++i] - 0x20));
			} else {
				sb.append(chars[i]);
			}
		}

		return sb.toString();
	}

	public static List<Integer> splitStringList(String str) {
		return splitStringList(str, ",");
	}

	public static List<Integer> splitStringList(String str, String spitStr) {
		if (StringUtils.isBlank(str))
			return new ArrayList<Integer>();
		String[] ss = str.split(spitStr);
		try {
			List<Integer> list = new ArrayList<Integer>();
			for (String s : ss) {
				list.add(Integer.parseInt(s));
			}
			return list;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return new ArrayList<Integer>();
	}

	public static List<Integer> splitStringListNotZeroRepeat(String str, String spitStr) {
		if (StringUtils.isBlank(str))
			return new ArrayList<Integer>();
		String[] ss = str.split(spitStr);
		try {
			List<Integer> list = new ArrayList<Integer>();
			for (String s : ss) {
				int num = Integer.parseInt(s);
				if (num <= 0 || list.contains(num))
					continue;
				list.add(num);
			}
			return list;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return new ArrayList<Integer>();
	}

	/**
	 * 得到以逗号为区分的字符串 @author xingyao @date 2017年2月14日 @param @return @exception
	 */
	public static String getCommaStr(Object[] objs) {
		return getConjStr(objs, ",");
	}

	/**
	 * 以连接词连接字符串数组 @author xingyao @date 2017年2月15日 @param @return @exception
	 */
	public static String getConjStr(Object[] objs, String conj) {
		if (objs == null || objs.length <= 0) {
			return "";
		}
		String inWhere = " ";
		for (int i = 0; i < objs.length; i++) {
			if (i == objs.length - 1) {
				inWhere += objs[i];
			} else {
				inWhere += objs[i] + " " + conj + " ";
			}
		}
		return inWhere;
	}

	/**
	 * 得到以逗号为区分的字符串 @title getInWhere @author :
	 * xingyao @time:2017年1月21日 @Description 描述：得到SQL的int 查询条件 @return
	 * String @throws
	 */
	public static String getCommaStr(List<?> lists) {
		Object[] objs = lists.toArray();
		return getCommaStr(objs);
	}

	/**
	 * 使用and连接数组 @author xingyao @date 2017年2月15日 @param @return @exception
	 */
	public static String getAndStr(List<?> lists) {
		if(lists == null || lists.size() == 0){
			return "";
		}
		Object[] objs = lists.toArray();
		return getConjStr(objs, " and ");
	}

	/**
	 * 将一个字符串的下标为index的字母转化为大写 @author xingyao @date
	 * 2017年2月14日 @param @return @exception
	 * @throws Exception 
	 */
	public static String toHighIndex(String str, int index) throws Exception {
		if (StringUtil.isEmpty(str)) {
			return str;
		}
		if (index < 0 || index > str.length() - 1) {
			throw new Exception("参数异常");
		}
		String highChar = str.charAt(index) + "";
		highChar = highChar.toUpperCase();
		String firstStr = str.substring(0, index);
		String secondStr = str.substring(index + 1, str.length());
		return firstStr + highChar + secondStr;
	}

	
	/**
	 * 数据加密
	 * @author xingyao
	 * @date 2017年2月20日
	 * @describe
	 * @param plainText
	 * @throws SystemException 
	 */
	public static String toMD5(String plainText) throws Exception {
		try {
			// 生成实现指定摘要算法的 MessageDigest 对象。
			MessageDigest md = MessageDigest.getInstance("MD5");
			// 使用指定的字节数组更新摘要。
			md.update(plainText.getBytes());
			// 通过执行诸如填充之类的最终操作完成哈希计算。
			byte b[] = md.digest();
			// 生成具体的md5密码到buf数组
			int i;
			StringBuffer buf = new StringBuffer("");
			for (int offset = 0; offset < b.length; offset++) {
				i = b[offset];
				if (i < 0)
					i += 256;
				if (i < 16)
					buf.append("0");
				buf.append(Integer.toHexString(i));
			}
			return buf.toString();
		} catch (Exception e) {
			throw new Exception("MD5解析错误");
		}
	}
	
	/**
	 * 把 .0转成空字符串
	 * @author xiehua
	 * @param str
	 * @return
	 */
	public static String toNoPointZeroTime(String str){
		if(StringUtil.isEmpty(str)){
			return str;
		}
		return str.replace(".0", "");
	}
	
	
	/**
	 * 得到学年信息
	 * @author xingyao
	 * @date 2017年3月8日
	 * @describe
	 * @return
	 */
	public static String getNowSchool_year(){
		Calendar calendar=Calendar.getInstance();
		int year = calendar.get(Calendar.YEAR);
		int month = calendar.get(Calendar.MONTH);
		String school_year = "";
		if(month <= 8){
			school_year =  (year-1)+"2";
		}else{
			school_year =  year+"1";
		}
		return school_year;
	}
	
	/**
	 * 获取验证码
	 * 
	 * @return
	 */
	public static String getVerificationCode() {
		String verificationCode = "";
		String[] code = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
				"t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N",
				"O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "1", "2", "3", "4", "5", "6", "7", "8", "9",
				"0" };
		for (int i = 0; i < 4; i++) {
			verificationCode += code[(int) Math.floor(Math.random() * (code.length - 1))];
		}
		return verificationCode;
	}
	
	/**
	 * 得到随机字符串
	 * @author xingyao
	 * @date 2017年4月5日
	 * @describe
	 * @param number 得到字符串的长度
	 * @return
	 */
	public static String getRandom(int number) {
		String verificationCode = "";
		String[] code = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
				"t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N",
				"O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "1", "2", "3", "4", "5", "6", "7", "8", "9",
		"0" };
		for (int i = 0; i < number; i++) {
			verificationCode += code[(int) Math.floor(Math.random() * (code.length - 1))];
		}
		return verificationCode;
	}
	
	
	/*将string类型转化为boolean类型*/
	public static boolean StringToBoolean(String boo){
		if(!StringUtil.isEmpty(boo)){
			if(boo.equalsIgnoreCase("true")){
				return true;
			}
		}
		return false;
	}
	
	
	/**
	 * 如果是message是以str开头，则去掉str
	 * @author xingyao
	 * @date 2017年4月28日
	 * @describe
	 * @param str
	 */
	public static String ifStrBeginRemove(String str,String message){
		if(message.trim().startsWith(str)){
			int index = message.indexOf(str);
			
			message = message.substring(index+1, message.length());
		}
		return message;
	}

	/**
	 * 将第一个String转为大写
	 * @param str
	 * @return
	 */
	public static String tranFirstToBig(String str){
		if (StringUtils.isBlank(str)){
			return str;
		}
		return str.substring(0, 1).toUpperCase() + str.substring(1);
	}

	public static StringBuffer getMiniSign(SortedMap<String, Object> map) {
		if (map == null) {
			return null;
		}
		StringBuffer sb = new StringBuffer();
		Set<String> keys = map.keySet();
		for (Iterator<String> iterator = keys.iterator(); iterator.hasNext();) {
			String key = (String) iterator.next();
			sb.append(key + "=" + map.get(key) + "&");
		}
		return sb;
	}

	public static String toMiniWechatPayXml(SortedMap<String, Object> map) {
		StringBuffer sb = new StringBuffer();
		sb.append("<xml>");
		Set<String> keys = map.keySet();
		for (Iterator<String> iterator = keys.iterator(); iterator.hasNext();) {
			String key = (String) iterator.next();
			sb.append("<"+key+">");
			sb.append(map.get(key));
			sb.append("</"+key+">");
		}
		sb.append("</xml>");
		return sb.toString();
	}

}
